// 用于学习pending（未决）相关内容

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <signal.h>
#include <cassert>
using namespace std;

void PrintPending(const sigset_t pending)
{
    cout << "当前进程的pending:";
    for (int signo = 1; signo <= 31; signo++)
    {
        if (sigismember(&pending, signo))
            cout << "1";
        else
            cout << "0";
    }
    cout << "\n";
}

void test_1() // 屏蔽二号信号
{
    // 屏蔽2号信号
    sigset_t set, oset;
    // 初始化
    sigaddset(&set, SIGINT);
    // 将新的信号屏蔽字设置进入进程
    sigprocmask(SIG_BLOCK, &set, &oset);

    // 获取进程的pending信号集，并打印
    while (true)
    {
        // 获取pending信号集
        sigset_t pending;
        sigemptyset(&pending);
        int n = sigpending(&pending);
        assert(n == 0);
        (void)n;

        // 打印
        PrintPending(pending);
        sleep(1);
    }
}

void handler(int signo)
{
    cout << "对特定信号:" << signo << "执行捕捉动作" << endl;
}

void test_2() // 屏蔽信号并恢复
{
    // 设置对2号信号的自定义捕捉
    // 避免捕捉到二号信号后进程终止
    signal(2, handler);
    int cnt = 0;

    // 屏蔽2号信号
    sigset_t set, oset;
    // 初始化
    sigemptyset(&set);
    sigemptyset(&oset);
    sigaddset(&set, SIGINT);
    // 将新的信号屏蔽字设置进入进程
    sigprocmask(SIG_BLOCK, &set, &oset);

    // 获取进程的pending信号集，并打印
    while (true)
    {
        // 获取pending信号集
        sigset_t pending;
        sigemptyset(&pending);
        int n = sigpending(&pending);
        assert(n == 0);
        (void)n;

        // 打印
        PrintPending(pending);
        sleep(1);

        if (cnt++ == 10)
        {
            cout << "解除对2号信号的屏蔽" << endl;
            sigprocmask(SIG_SETMASK, &oset, nullptr);
        }
    }
}

int main()
{
    // test_1();
    test_2();
    return 0;
}